package com.xinqiupark.technology.view;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.LinearInterpolator;

import com.xinqiupark.technology.util.DensityUtil;

import java.text.DecimalFormat;

/**
 * @author Steven.zhao
 * email:hongtu.zhao@goodwinsoft.net
 * date:2018/9/17
 * desc:自定义水平进度条
 */
public class HorizontalProgressBar extends View {

    private Paint mBgPaint;
    private Paint mProgressPaint;

    private Paint mTipPaint;
    private Paint mTextPaint;

    private int mWidth;
    private int mHeight;
    private int mViewHeight;

    private int progressPaintWidth;

    //提示框画笔宽度
    private int tipPaintWidth;
    //提示框宽度
    private int tipWidth;
    //提示框高度
    private int tipHeight;

    //三角形高度
    private int triangleHeight;

    //进度条具体气泡距离
    private int progressMarginTop;
    //百分比文字大小
    private int textPaintSize;
    //圆角矩形的圆角半径
    private int roundRectRadius;

    /**
     * 进度条背景颜色
     */
    private int bgColor = 0xFFe1e5e8;
    /**
     * 进度条颜色
     */
    private int progressColor = 0xFFf66b12;

    //当前进度
    private float currentProgress = 0;
    //进度
    private float mProgress;
    private ValueAnimator mProgressAnimator;

    /**
     * 动画执行时间
     */
    private int duration = 1000;
    /**
     * 动画延时启动时间
     */
    private int startDelay = 500;

    //设置进度回调监听
    private ProgressListener progressListener;

    private RectF rectF=new RectF();

    private Path path = new Path();

    private Rect textRect = new Rect();

    //进度移动的距离
    private float moveDis;

    private String textString = "0";


    public HorizontalProgressBar(Context context) {
        this(context, null);
    }

    public HorizontalProgressBar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        init();
        initPaint();
    }


    /**
     * 初始化操作
     */
    private void init() {
        progressPaintWidth = dp2px(4);
        tipPaintWidth = dp2px(1);
        tipHeight = dp2px(15);
        tipWidth = dp2px(30);
        triangleHeight = dp2px(3);
        roundRectRadius = dp2px(2);
        textPaintSize = dp2px(10);
        progressMarginTop = dp2px(8);

        //view的真实高度
        mViewHeight = tipHeight + tipPaintWidth + triangleHeight + progressMarginTop + progressPaintWidth;
    }

    /**
     * 初始化画笔
     */
    private void initPaint() {
        mBgPaint = getPaint(progressPaintWidth, bgColor, Paint.Style.STROKE);
        mProgressPaint = getPaint(progressPaintWidth, progressColor, Paint.Style.STROKE);
        mTipPaint=getPaint(tipPaintWidth,progressColor,Paint.Style.FILL);

        initTextPaint();
    }

    /**
     * 初始化文字画笔
     */
    private void initTextPaint() {
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setTextSize(textPaintSize);
        mTextPaint.setColor(Color.WHITE);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.setAntiAlias(true);
    }

    /**
     * 同意处理Paint
     */
    private Paint getPaint(int strokeWidth, int color, Paint.Style style) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

        paint.setStrokeWidth(strokeWidth);
        paint.setColor(color);
        paint.setAntiAlias(true);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStyle(style);
        return paint;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        setMeasuredDimension(measureWidth(widthMode, width), measureHeight(heightMode, height));
    }

    private int measureHeight(int heightMode, int height) {
        switch (heightMode) {
            case MeasureSpec.UNSPECIFIED:
            case MeasureSpec.AT_MOST:
                mHeight = mViewHeight;
                break;
            case MeasureSpec.EXACTLY:
                mHeight = height;
                break;
        }
        return mHeight;
    }

    private int measureWidth(int widthMode, int width) {
        switch (widthMode) {
            case MeasureSpec.UNSPECIFIED:
            case MeasureSpec.AT_MOST:
                break;
            case MeasureSpec.EXACTLY:
                mWidth = width;
                break;
        }
        return mWidth;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //绘制背景
        canvas.drawLine(getPaddingLeft(), tipHeight + progressMarginTop
                , getWidth(), tipHeight + progressMarginTop, mBgPaint);

        //绘制真实进度
        canvas.drawLine(getPaddingLeft(),
                tipHeight + progressMarginTop
                , currentProgress,
                tipHeight + progressMarginTop, mProgressPaint);

        drawTipView(canvas);
        drawText(canvas, textString);
    }

    //绘制进度提示view
    private void drawTipView(Canvas canvas) {
        drawRoundRect(canvas);
        drawTriangle(canvas);
    }

    /**
     * 绘制圆角矩形
     */
    private void drawRoundRect(Canvas canvas) {
        rectF.set(moveDis,0,tipWidth+moveDis,tipHeight);
        canvas.drawRoundRect(rectF,roundRectRadius,roundRectRadius,mTipPaint);
    }

    /**
     * 绘制文字
     */
    private void drawText(Canvas canvas, String textString) {
        textRect.left= (int) moveDis;
        textRect.top=0;
        textRect.right = (int) (tipWidth + moveDis);
        textRect.bottom = tipHeight;

        Paint.FontMetricsInt fontMetrics=mTextPaint.getFontMetricsInt();
        int baseline = (textRect.bottom + textRect.top - fontMetrics.bottom - fontMetrics.top) / 2;
        canvas.drawText(textString+"%",textRect.centerX(),baseline,mTextPaint);
    }


    //绘制三角形
    private void drawTriangle(Canvas canvas) {
        path.moveTo(tipWidth/2-triangleHeight+moveDis,tipHeight);
        path.lineTo(tipWidth / 2 + moveDis, tipHeight + triangleHeight);
        path.lineTo(tipWidth / 2 + triangleHeight + moveDis, tipHeight);
        canvas.drawPath(path,mTipPaint);
        path.reset();
    }

    /**
     * 设置进度带有动画效果
     */
    public HorizontalProgressBar setProgressWithAnimation(float progress) {
        mProgress = progress;
        initAnimation();
        return this;
    }

    /**
     * 进度移动动画  通过插值的方式改变移动的距离
     */
    private void initAnimation() {
        mProgressAnimator = ValueAnimator.ofFloat(0, mProgress);
        mProgressAnimator.setDuration(duration);
        mProgressAnimator.setStartDelay(startDelay);

        mProgressAnimator.setInterpolator(new LinearInterpolator());
        mProgressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                float value = (float) valueAnimator.getAnimatedValue();
                textString = formatNum(format2Int(value));
                currentProgress = value * mWidth / 100;

                if (progressListener != null) {
                    progressListener.currentProgressListener(value);
                }
                if (currentProgress >= (tipWidth / 2) &&
                        currentProgress <= (mWidth - tipWidth / 2)) {
                    moveDis = currentProgress - tipWidth / 2;
                }
                invalidate();
            }
        });

        mProgressAnimator.start();
    }

    /**
     * 实时显示进度
     *
     */
    public HorizontalProgressBar setCurrentProgress(float progress) {
        mProgress = progress;
        currentProgress = progress * mWidth / 100;
        textString = formatNum(format2Int(progress));
        invalidate();
        return this;
    }

    /**
     * 开启动画
     */
    public void startProgressAnimation() {
        if (mProgressAnimator != null &&
                !mProgressAnimator.isRunning() &&
                !mProgressAnimator.isStarted())
            mProgressAnimator.start();
    }

    /**
     * 暂停动画
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public void pauseProgressAnimation() {
        if (mProgressAnimator != null) {
            mProgressAnimator.pause();
        }
    }

    /**
     * 恢复动画
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public void resumeProgressAnimation() {
        if (mProgressAnimator != null)
            mProgressAnimator.resume();
    }

    /**
     * 停止动画
     */
    public void stopProgressAnimation() {
        if (mProgressAnimator != null) {
            mProgressAnimator.end();
        }
    }


    /**
     * dp 2 px
     *
     * @param dpVal
     */
    protected int dp2px(int dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal, getResources().getDisplayMetrics());
    }

    /**
     * sp 2 px
     *
     * @param spVal
     * @return
     */
    protected int sp2px(int spVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                spVal, getResources().getDisplayMetrics());

    }

    public static int format2Int(double i) {
        return (int) i;
    }

    /**
     * 格式化数字(保留两位小数)
     *
     * @param money
     * @return
     */
    public static String formatNumTwo(double money) {
        DecimalFormat format = new DecimalFormat("0.00");
        return format.format(money);
    }

    /**
     * 格式化数字(保留一位小数)
     *
     * @param money
     * @return
     */
    public static String formatNum(int money) {
        DecimalFormat format = new DecimalFormat("0");
        return format.format(money);
    }


    /**
     * 回调监听
     */
    public interface ProgressListener {
        void currentProgressListener(float currentProgress);
    }

    /**
     * 回调监听事件
     */
    public HorizontalProgressBar setProgressListener(ProgressListener progressListener) {
        this.progressListener = progressListener;
        return this;
    }
}
